package com.lill.support.aspect;

import java.util.concurrent.TimeUnit;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.codec.digest.DigestUtils;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import org.springframework.web.multipart.MultipartFile;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.lill.common.system.exception.NoRepeatException;
import com.lill.system.service.ICommonRedisService;

@Component
@Aspect
public class NoRepeatSubmitWebAopAspect {
	
	protected static Logger logger = LoggerFactory.getLogger(NoRepeatSubmitWebAopAspect.class);
	
	@Autowired
	private ICommonRedisService commonRedisService;
	private final ObjectMapper mapper;
	
	@Autowired
	public NoRepeatSubmitWebAopAspect(ObjectMapper mapper) {
		this.mapper = mapper;
	}

	/**
	 *  web 后台 防止重复提交
	 */
	@Pointcut("@annotation(com.lill.support.annotation.WebOnceSubmit)")
	public void apiParamsPointcut() {
	}

	@Before("apiParamsPointcut()")
	public void doBefore(JoinPoint point) {
		ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
    	HttpServletRequest request = attributes.getRequest();
    	String uri=request.getRequestURI();
    	logger.info("uri:"+uri);
		
		StringBuffer params=new StringBuffer("md5");
    	for (Object object : point.getArgs()) {
    		if(null==object){
    			continue;
    		}
    		
    		if (object.toString().indexOf("Response")>=0) {
    			continue;
    		}
    		if (object.toString().indexOf("Request")>=0) {
    			continue;
    		}
    		
    		if (object instanceof MultipartFile) {
    			MultipartFile file=(MultipartFile) object;
    			params.append(file.getName());
    			continue;
			}
    		
    		if (object instanceof MultipartFile[]) {
    			MultipartFile[] files=(MultipartFile[]) object;
    			for (MultipartFile file : files) {
    				params.append(file.getName());
				}
    			continue;
    		}
    		
    		try {
				params.append(mapper.writeValueAsString(object));
			} catch (Exception e) {
				logger.error(object.toString());
				logger.error(e.getMessage(), e);
				continue;
			}
    	}
    	
    	logger.info("NoRepeatSubmitWebAopAspect:"+params.toString());
    	
    	String key="NoRepeatSubmit:"+request.getSession().getId()+uri+DigestUtils.md5Hex(params.toString()).toUpperCase();
    	logger.info("NoRepeatSubmitWebAopAspect:"+key);
    	if (commonRedisService.getIntegerValueByKey(key) == null) {
        	commonRedisService.setKeyStringValueIntegerWithTime(key, 0, 5, TimeUnit.SECONDS);
        }else{
        	throw new NoRepeatException("请理智操作");
        }
	}
 
}
